#include "app_buffer.h"
#include <stdlib.h>
#include <string.h>
#include "log/log.h"

//初始化小缓冲区
static SubBuffer *sub_buffer_init(int size){
    SubBuffer *sub_buffer=(SubBuffer*)malloc(sizeof(SubBuffer));
    sub_buffer->ptr=(char*)malloc(size);
    sub_buffer->size=size;
    sub_buffer->len=0;
    return sub_buffer;

}


//初始化缓冲区
Buffer *app_buffer_init(int size){
    //内存申请
    Buffer *buffer=(Buffer*)malloc(sizeof(Buffer));

    //内部属性初始化
    buffer->sub_buffers[0]=sub_buffer_init(size);
    buffer->sub_buffers[1]=sub_buffer_init(size);
    buffer->read_index=0;
    buffer->write_index=1;

    //读写锁的初始化
    pthread_mutex_init(&buffer->read_lock,NULL);
    pthread_mutex_init(&buffer->write_lock,NULL);

    return buffer;
}

//释放缓冲区
void app_buffer_free(Buffer *buffer){
    free(buffer->sub_buffers[0]->ptr);
    free(buffer->sub_buffers[0]);
    free(buffer->sub_buffers[1]->ptr);
    free(buffer->sub_buffers[1]);
    free(buffer);
}

//写入数据到缓冲区
int app_buffer_write(Buffer *buffer, char *data, int len){
    //写入数据判断数据长度是否合法
    if (len>255)
    {
        log_error("len>255,数据长度不合法");
        return -1;
    }
    //添加写入锁
    log_debug("添加写锁");

    pthread_mutex_lock(&buffer->write_lock);
    log_debug("获得写锁");

    //获取写的小的buffer
    SubBuffer *sub_buffer=buffer->sub_buffers[buffer->write_index];
    //判断小缓冲区是否有足够的空间
    if (sub_buffer->size - sub_buffer->len < len + 1)
    {
        log_error("小缓冲区没有足够的空间");
        pthread_mutex_unlock(&buffer->write_lock);
        log_debug("释放写锁");
        return -1;
    }
    //写入数据
    sub_buffer->ptr[sub_buffer->len] = (char)len; //写入数据长度
    memcpy(sub_buffer->ptr + sub_buffer->len + 1, data, len);
    sub_buffer->len += (len + 1); //更新小缓冲区的长度

    //释放写入锁
    log_debug("释放写锁");
    pthread_mutex_unlock(&buffer->write_lock);
    return 0;
    
}
void swap_sub_buffer(Buffer *buffer) {  

    // 加写锁
    log_debug("交互前，加写锁");
    pthread_mutex_lock(&buffer->write_lock);
    int tmp = buffer->read_index;
    buffer->read_index = buffer->write_index;
    buffer->write_index = tmp;
    // 解写锁
    log_debug("交互后，解写锁");
    pthread_mutex_unlock(&buffer->write_lock);
}

//从缓冲区读取数据
int app_buffer_read(Buffer *buffer, char *data_buf, int buf_size){
    //读取小的buffer
    SubBuffer *sub_buffer=buffer->sub_buffers[buffer->read_index];
    //判断小缓冲区是否有数据
    if (sub_buffer->len==0)
    {
        swap_sub_buffer(buffer);
  sub_buffer=buffer->sub_buffers[buffer->read_index];
     //如果交互后还是没有数据，说明没有数据可读
        if (sub_buffer->len==0)
        {
            log_debug("没有数据可读");
            return 0;
        }
}
  //读取数据长度
  int len=sub_buffer->ptr[0];
  //如果容器大小不够
    if (buf_size<len)
    {
        log_error("buf_size<len,容器大小不够");
        return -1;
    }
    //读取相应的数据 ，保存到data_buf中
    memcpy(data_buf,sub_buffer->ptr+1,len);

    //后面的数据前移
    memmove(sub_buffer->ptr,sub_buffer->ptr+len+1,sub_buffer->len-(len+1));
    //更新小缓冲区的长度
    sub_buffer->len-=(len+1);

    //释放读锁
    pthread_mutex_unlock(&buffer->read_lock);
    log_debug("释放读锁");
    return len;
}
